package com.dawnling.androidutils.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.PathEffect;
import android.graphics.Point;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ScreenUtils;
import com.blankj.utilcode.util.ToastUtils;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 本地视频调试横屏绘制区域画线View
 * Created by dawnLing on 2020/09/30.
 */
public class KTPaintAreaView extends View {

    //圆点数组
    private List<Point> roundPoints = new ArrayList<>();
    private float dashSize = 10;//虚线大小
    private boolean isExit = false;//是否显示全屏UI界面底部tab菜单按钮
    private Handler handler = new Handler();//计时器
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            isExit = false;
            if (mListener != null) mListener.passState(true);
        }
    };

    //接受context以及属性集合(宽度，高度等)
    public KTPaintAreaView(Context context, AttributeSet attrs) {
        super(context, attrs);
        super.setOnTouchListener(new OnTouchListenerImp());
    }

    /**
     * 设置画线区域
     */
    public void changeRoundPoints(List<Point> roundPoints) {
        this.roundPoints.clear();
        this.roundPoints.addAll(roundPoints);
        invalidate();
    }

    /**
     * 动作常量：
     * MotionEvent.ACTION_DOWN：当屏幕检测到第一个触点按下之后就会触发到这个事件。
     * MotionEvent.ACTION_MOVE：当触点在屏幕上移动时触发，触点在屏幕上停留也是会触发的，主要是由于它的灵敏度很高，而我们的手指又不可能完全静止（即使我们感觉不到移动，但其实我们的手指也在不停地抖动）。
     * MotionEvent.ACTION_POINTER_DOWN：当屏幕上已经有触点处于按下的状态的时候，再有新的触点被按下时触发。
     * MotionEvent.ACTION_POINTER_UP：当屏幕上有多个点被按住，松开其中一个点时触发（即非最后一个点被放开时）触发。
     * MotionEvent.ACTION_UP：当触点松开时被触发。
     * MotionEvent.ACTION_OUTSIDE: 表示用户触碰超出了正常的UI边界.
     * MotionEvent.ACTION_SCROLL：android3.1引入，非触摸滚动，主要是由鼠标、滚轮、轨迹球触发。
     * MotionEvent.ACTION_CANCEL：不是由用户直接触发，由系统在需要的时候触发，例如当父view通过使函数onInterceptTouchEvent()返回true,从子view拿回处理事件的控制权时，就会给子view发一个ACTION_CANCEL事件，子view就再也不会收到后续事件了。
     */
    private class OnTouchListenerImp implements OnTouchListener {
        public boolean onTouch(View v, MotionEvent event) {
            Point p = new Point((int) event.getX(), (int) event.getY());
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                //用户按下，表示重新开始保存点
                LogUtils.e("onTouch ACTION_DOWN" + "{" + p.x + "," + p.y + "}");
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                //用户松开
                LogUtils.e("onTouch ACTION_UP" + "{" + p.x + "," + p.y + "}");
                isExit = true;
                handler.removeCallbacks(runnable);//移除上个定时器
                handler.postDelayed(runnable, 3000);//开始计时3s
                if (isExit) {
                    if (KTPaintAreaView.this.roundPoints.size() >= 20) { //最多20个点
                        ToastUtils.showShort("最多20个点~");
                        return true;
                    }
                    if (!KTPaintAreaView.this.roundPoints.contains(p)) {
                        KTPaintAreaView.this.roundPoints.add(p);
                        LogUtils.e("onTouch ACTION_UP roundPoints长度=" + KTPaintAreaView.this.roundPoints.size() + ",roundPoints=" + KTPaintAreaView.this.roundPoints);
                        KTPaintAreaView.this.postInvalidate();
                        if (mListener != null) {
                            mListener.pointList(p, roundPoints);
                            mListener.passState(false);
                        }
                    }
                }
            } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                LogUtils.e("onTouch ACTION_MOVE" + "{" + p.x + "," + p.y + "}");
            }
            return true;
        }
    }

    @SuppressLint("MissingSuperCall")
    @Override
    public void draw(Canvas canvas) {
        Paint p = new Paint();//依靠此类开始画线
        p.setColor(Color.BLUE);
        p.setStrokeWidth(3);
        PathEffect pathEffect = new DashPathEffect(new float[]{dashSize, dashSize, dashSize, dashSize}, 1);
        p.setPathEffect(pathEffect);

        List<Point> roundPoints = KTPaintAreaView.this.roundPoints;
        for (int i = 0; i < roundPoints.size(); i++) {
            //画圆点 定义一个矩形区域
            canvas.drawCircle(roundPoints.get(i).x, roundPoints.get(i).y, 10, p);
        }
        if (roundPoints.size() > 1) {
            //如果有坐标点，开始绘图
            Iterator<Point> iter = roundPoints.iterator();
            Point firstOriginal = null;//第一个点 原点保持不变
            Point first = null;
            Point last = null;
            while (iter.hasNext()) {
                if (firstOriginal == null) firstOriginal = iter.next();
                if (first == null) {
                    first = firstOriginal;//绘制线的起点
                } else {
                    if (last != null) first = last;
                    last = iter.next();////绘制线的结束点
                    canvas.drawLine(first.x, first.y, last.x, last.y, p);
                }
                //绘制闭合点
                if (roundPoints.size() > 2 && !iter.hasNext()) {
                    canvas.drawLine(last.x, last.y, firstOriginal.x, firstOriginal.y, p);
                }
            }
        }
    }

    /**
     * 对画布进行清屏
     */
    public void clearDraw() {
        roundPoints.clear();
        invalidate();
    }

    public PointsListener mListener = null;

    public interface PointsListener {
        void pointList(Point points, List<Point> list);

        void passState(boolean isExit);
    }

    //相机宽高
    public static float cameraWidth = 1280;
    public static float cameraHeight = 720;

    /**
     * 实际手机屏幕坐标转换为相机坐标
     * 相机坐标720*1280
     * KTPaintAreaView.phone2Camera(roundPointsLeft)
     */
    public static List<Point> phone2Camera(List<Point> list) {
        List<Point> resultsList = new ArrayList<>();
        int width = ScreenUtils.getScreenWidth();//例如1520
        int height = ScreenUtils.getScreenHeight();//例如720
        LogUtils.e("屏幕宽高：width=" + width + ";height=" + height);
        //比例
        float xScale = cameraWidth / width;
        float yScale = cameraHeight / height;
        resultsList.clear();
        for (int i = 0; i < list.size(); i++) {
            int x = list.get(i).x;
            int y = list.get(i).y;
            resultsList.add(new Point((int) (xScale * x), (int) (yScale * y)));
        }
        LogUtils.e("转换前数组list：" + list);
        LogUtils.e("转换后数组resultsList：" + resultsList);
        return resultsList;
    }
}
